#include <stdlib.h>
#include <stdio.h>
#include "globals.h"
//#include "pcb.c"
#ifndef IO_device_
#define IO_device_

//process at the head of the queue, is the process whose io request is being processed currently.
typedef struct io_dev {
        int size;
		int count;
		char name[5];
        PCBStr *head;
        PCBStr *tail;
} io_device;

io_device* video_io;
io_device* disk_io;

//head and tail are dummy pcb's
io_device* create_io_device()
{
	io_device* device = malloc(sizeof(io_device));
	device->head = malloc(sizeof(PCBStr));
	device->tail = malloc(sizeof(PCBStr));
	puts("IO Device created.\n");
	device->size = 0;
	device->count = 0;
	device->head->prev = NULL;
	device->head->next = device->tail;
	device->tail->next = NULL;
	device->tail->prev = device->head;
	return device;

}


void set_up_disk()
{
	disk_io = create_io_device();
	strcpy(disk_io->name, "Disk");
	puts("Disk device and queue setup.\n");
}

void set_up_video()
{
	video_io = create_io_device();
	strcpy(video_io->name, "Video");
	puts("Video device and queue setup.\n");
}


void add_pcb_io_blocked_queue(PCBStr *pcb, io_device *device)
{
 pcb->next =  device->tail;
 pcb->prev =  device->tail->prev;
 device->tail->prev->next = pcb; 
 device->tail->prev =  pcb;
 device->size++;
  if(device->name == "Video")
  {
    printf("Process %s added to blocked queue of IO device Video.\n", pcb->pid->name);
  }
  else
  {
    printf("Process %s added to blocked queue of IO device Disk.\n", pcb->pid->name);
  }
}

void process_next_process_blocked_queue(io_device *device)
{
	
	PCBStr *temp;
	if(device->size == 0)
	{
		printf("%s's blocked queue is empty, no processes waiting.\n", device->name);
	}
	else
	{
		device->count = rand_num();
		temp = device->head->next;
		device->head->next = temp->next;
		temp->next->prev = device->head;
		device->size--;
    	        printf("%s is done processing %s.\n", device->name, temp->pid->name);
		printf("%s is now processing %s.\n", device->name, device->head->next->pid->name);

	}
}


PCBStr *blocked_queue_process_remove(io_device *device) {
        PCBStr *skipped;
        if (device == NULL || (device != NULL && device->size == 0)) {
                puts("IO device queue provided is NULL or empty, exiting...");
                exit(-1);
        }

        else
        {
                skipped = device->head->next;
                device->head->next = skipped->next;
                device->head->next->prev = device->head;
                skipped->next->prev = skipped->prev;
                device->size--;
                printf("Process %s removed from IO device %s queue.\n", skipped->pid->name, device->name);

        }
        return skipped;
}


#endif

